#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/io.h>



#define CNT_EIM (2)

struct misc_eim_data {
	char name[16];
	int voltage;
	int temp_integer;
	int temp_decimal;
};


static ssize_t name_show(
    struct device *dev,
    struct device_attribute *attr,
    char *buf)
{
	struct misc_eim_data *pdata = (struct misc_batt_data *)dev->platform_data;
	volatile unsigned int *sdram0, *sdram1, *sdram2, *sdram3, *sdram4;
	unsigned int data;
	volatile int i;
	sdram0 = ioremap(0x08000000+ 4*0, 1024*4);
	sdram1 = ioremap(0x08000000+ 4*1, 1024*4);
	sdram2 = ioremap(0x08000000+ 4*2, 1024*4);
	sdram3 = ioremap(0x08000000+ 4*3, 1024*4);
	sdram4 = ioremap(0x08000000 +4*4,1024*4);
	for (i = 0;i < 40;i++) {
		// data = *(sdram0+i);
		// data = *sdram0;
		// data = *sdram0;
		// data = *sdram0;
		// data = *sdram1;
		// data = *sdram2;
		// data = *sdram3;
		// data = *sdram4;
		
		*(sdram0+i) = 0xffffa5f3;
		// *sdram1 = 0xffffffff;
		// *sdram2 = 0xffffffff;
		// *sdram3 = 0xffffffff;
		// *sdram4 = 0xffffffff;
	}
	// printk("sdram: %8x\r\n", *sdram);
	printk("sdram: %8x %8x\n", *sdram0, *sdram1);
	printk("data: %8x\n", data);
	iounmap(sdram0);
	iounmap(sdram1);
	iounmap(sdram2);
	iounmap(sdram3);
	iounmap(sdram4);
	
	return sprintf(buf, "%s\n", pdata->name);
}

static ssize_t eim_voltage_show(
    struct device *dev,
    struct device_attribute *attr,
    char *buf)
{
	struct misc_eim_data *pdata = (struct misc_eim_data *)dev->platform_data;
	volatile unsigned long * sdram;
	sdram = (volatile unsigned long *)ioremap(0x08000000, 1024);
	printk("sdram: %8x\r\n", *sdram);
	iounmap(sdram);
	return snprintf(buf, PAGE_SIZE, "%d\n", pdata->voltage);
}
static ssize_t eim_voltage_store(
    struct device *dev,
    struct device_attribute *attr,
    const char *buf, size_t count)
{
	struct misc_eim_data *pdata = (struct misc_eim_data *)dev->platform_data;
	char *after;
	int dat;
	int integer;
	int decimal;

	pdata->voltage = simple_strtoul(buf, &after, 10);

	// 电压转换成温度
	dat                 = pdata->voltage - 750;
	integer             = dat / 10;
	decimal             = (dat - integer * 10);
	pdata->temp_integer = integer + 25;
	pdata->temp_decimal = decimal;
	return count;
}


static ssize_t eim_temp_show(
    struct device *dev,
    struct device_attribute *attr,
    char *buf)
{
	struct misc_eim_data *pdata = (struct misc_eim_data *)dev->platform_data;
	return snprintf(buf, PAGE_SIZE, "%d.%d\n",
	                pdata->temp_integer,
	                abs(pdata->temp_decimal));
}


static DEVICE_ATTR(
    name, S_IRUGO, name_show, NULL);
static DEVICE_ATTR(
    voltage, S_IWUSR | S_IRUGO, eim_voltage_show, eim_voltage_store);
static DEVICE_ATTR(
    temp, S_IRUGO, eim_temp_show, NULL);
static struct miscdevice *pmisc;




int __init eim_init(void)
{
	int                   i;
	char                  name[16];
	struct device        *this_dev;
	struct miscdevice    *tpmisc;
	struct misc_eim_data *pdata, *tpdata;

	pmisc = kzalloc(sizeof(struct miscdevice) * CNT_EIM, GFP_KERNEL);
	pdata = kzalloc(sizeof(struct misc_eim_data) * CNT_EIM, GFP_KERNEL);

	tpdata = pdata, tpmisc = pmisc;
	printk("sssssssss\r\n");
	for (i = 0; i < CNT_EIM; i++) {
		snprintf(name, sizeof(name), "eim%d", i);
		tpmisc->name  = name;
		tpmisc->minor = MISC_DYNAMIC_MINOR;
		tpmisc->fops  = NULL;
		misc_register(tpmisc);

		this_dev                = tpmisc->this_device;
		this_dev->platform_data = tpdata;

		tpdata->voltage         = 750;  /* 默认750mV 大约20℃， */
		tpdata->temp_integer    = 25;   /* 默认温度 25.0 */
		tpdata->temp_decimal    = 0;
		strcpy(tpdata->name, name);

		device_create_file(this_dev, &dev_attr_name);
		device_create_file(this_dev, &dev_attr_voltage);
		device_create_file(this_dev, &dev_attr_temp);
		tpmisc++, tpdata++;
	}
	return 0;
}

void __exit eim_exit(void)
{
	int i;
	struct miscdevice *tpmisc;

	if (pmisc) {
		tpmisc = pmisc;
		for (i = 0; i < CNT_EIM; i++) {
			misc_deregister(tpmisc);
			tpmisc++;
		}
		kfree(pmisc);
	}
}


#if 0
module_init(eim_init);
module_exit(eim_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("glink devices user space export");
#endif
